//
//  MTParseXML.m
//  ASITest
//
//  Created by zrz on 11-7-15.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "MTParseXML.h"

#define CheckNil	if(!self.obj) return nil;
#define DOCUMENT	((MTParseXML*)self.document)
#define	UTF8Code	"UTF-8"
#define LAST		nil


//-----------------------------MTParseXMLAttr-------------------------
#pragma mark -
#pragma mark attr

@implementation MTParseXMLAttr

+ (id)objWithPoint:(void*)obj Super:(id)superObj Document:(id)doc
{
	return [[MTParseXMLAttr alloc] initWithPoint:obj Super:superObj Document:doc];
}

- (id)initWithPoint:(void*)tobj Super:(id)tsuperObj Document:(id)doc
{
    self = [super initWithPoint:tobj Super:tsuperObj Document:doc];
	if (self) {
	}
	return self;
}

- (MTParseXMLAttr*)next
{
	CheckNil;
	return [MTParseXMLAttr objWithPoint:(((xmlAttrPtr)self.obj)->next) 
									Super:self.superObj 
								 Document:self.document];
}

- (MTParseXMLAttr*)prev
{
	CheckNil;
	return [MTParseXMLAttr objWithPoint:(((xmlAttrPtr)self.obj)->prev)
									Super:self.superObj
								 Document:self.document];
}

- (MTParseXMLAttr*)child
{
	CheckNil;
	return [MTParseXMLAttr objWithPoint:(((xmlAttrPtr)self.obj)->children)
									Super:self.superObj 
								 Document:self.document];
}

- (MTParseXMLAttr*)parent
{
	CheckNil;
	return [MTParseXMLAttr objWithPoint:(((xmlAttrPtr)self.obj)->parent)
									Super:self.superObj
								 Document:self.document];
}

- (NSString*)name
{
	CheckNil;
	if (!((xmlAttrPtr)self.obj)->name) {
		return nil;
	}
	return [NSString stringWithCString:(const char*)((xmlAttrPtr)self.obj)->name
                              encoding:DOCUMENT.encoding];
}

- (xmlElementType)type
{
	if (!self.obj) {
		return [super type];
	}
	return ((xmlAttrPtr)self.obj)->type;
}

@end

//-----------------------MTParseXMLPoint------------------------
#pragma mark -
#pragma mark node

@implementation MTParseXMLPoint

+ (id)objWithPoint:(void*)obj Super:(id)superObj Document:(id)doc
{
	return [[MTParseXMLPoint alloc] initWithPoint:obj Super:superObj Document:doc];
}

- (id)initWithPoint:(void*)tobj Super:(id)tsuperObj Document:(id)doc
{
    self = [super initWithPoint:tobj Super:tsuperObj Document:doc];
	if (self) {
	}
	return self;
}

- (NSString*)getContent
{
	CheckNil;
	xmlNodePtr tObj = ((xmlNodePtr)self.obj)->children;
	if (!tObj) {
		return nil;
	}
	if (!tObj->content) {
		return nil;
	}
	return [NSString stringWithCString:(const char*)tObj->content 
                              encoding:DOCUMENT.encoding];
}
- (NSString*)getAttr:(NSString*)tName
{
    if (!tName) {
        return nil;
    }
    NSStringEncoding encoding = DOCUMENT.encoding;
    const char* str = (const char*)xmlGetProp((xmlNodePtr)self.obj ,
                      (const xmlChar*)[tName cStringUsingEncoding:encoding]);
    if (!str) {
        return nil;
    }
    return [NSString stringWithCString: str
                              encoding:encoding];
}

- (MTParseXML*)Document
{
	return document;
}

- (MTParseXMLAttr*)getAttr
{
	CheckNil;
	return [MTParseXMLAttr objWithPoint:(((xmlNodePtr)self.obj)->properties) 
								  Super:self
							   Document:self.document];
}

- (MTParseXMLPoint*)next
{
	CheckNil;
	return [MTParseXMLPoint objWithPoint:(((xmlNodePtr)self.obj)->next) 
									Super:self.superObj
								 Document:self.document];
}

- (MTParseXMLPoint*)last
{
	CheckNil;
	return [MTParseXMLPoint objWithPoint:(((xmlNodePtr)self.obj)->last)
								   Super:self.superObj
								Document:document];
}

- (MTParseXMLPoint*)prev
{
	CheckNil;
	return [MTParseXMLPoint objWithPoint:(((xmlNodePtr)self.obj)->prev)
								   Super:self.superObj
								Document:self.document];
}

- (MTParseXMLPoint*)child
{
	CheckNil;
	return [MTParseXMLPoint objWithPoint:(((xmlNodePtr)self.obj)->children) 
									Super:self.superObj 
								 Document:self.document];
}

- (MTParseXMLPoint*)parent
{
	CheckNil;
	return [MTParseXMLPoint objWithPoint:(((xmlNodePtr)self.obj)->parent)
									Super:self.superObj 
								 Document:self.document];
}

- (NSString*)name
{
	CheckNil;
	if (!((xmlNodePtr)self.obj)->name) {
		return nil;
	}
	return [NSString stringWithCString:(const char*)((xmlNodePtr)self.obj)->name 
                              encoding:DOCUMENT.encoding];
}

- (xmlElementType)type
{
	if (!self.obj) {
		return [super type];
	}
	return ((xmlNodePtr)self.obj)->type;
}

- (MTParseXMLPoint*)childWithName:(NSString*)name index:(NSInteger)index
{
	const char* str = [name cStringUsingEncoding:DOCUMENT.encoding];
	int counter = 0;
	if (!((xmlNodePtr)self.obj)->children) return nil;
	for (xmlNodePtr node = ((xmlNodePtr)self.obj)->children ; 
					node != LAST ; 
					node = node->next) 
	{
		if (!node) break;
		if (!strcmp(str , (const char*)node->name)) {
			if (counter == index) {
				return [MTParseXMLPoint objWithPoint:node
											   Super:self.superObj
											Document:self.document];
			}
			counter++;
		}
	}
	return nil;
}

- (MTParseXMLAttr*)attrWithName:(NSString*)name index:(NSInteger)index
{
	const char* str = [name cStringUsingEncoding:DOCUMENT.encoding];
	int counter = 0;
	if (!((xmlNodePtr)self.obj)->properties) return nil;
	for (xmlAttrPtr attr = ((xmlNodePtr)self.obj)->properties ; 
					attr != LAST ;
					attr = attr->next) 
	{
		if (!attr) break;
		if (strcmp(str , (const char*)attr->name)) {
			if (counter == index) {
				return [MTParseXMLAttr objWithPoint:attr
											  Super:self
										   Document:self.document];
			}
			counter++;
		}
	}
	return nil;
}

@end


//--------------------------MTParseXML---------------------------
#pragma mark -
#pragma mark doc

@implementation MTParseXML

@synthesize error , encoding;

- (id)initWithData:(NSData*)data
{
    self = [super init];
    if (self) {
        obj = xmlParseMemory([data bytes] , [data length]);
        if (!obj) {
            error = [[NSError alloc] initWithDomain:@"file parse the memory." code:200 userInfo:nil];
            return self;
        }
        if (!strcmp((const char*)((xmlDocPtr)obj)->encoding , UTF8Code)) {
            encoding = NSUTF8StringEncoding;
        }else {
            encoding = NSUTF8StringEncoding;
        }
    }
    return self;
}

- (id)initWithPath:(NSString *)path
{
    self = [super init];
	if (self) {
		error = nil;
		[self openFile:path];
	}
	return self;
}

- (void)openFile:(NSString*)path
{
	if (obj) {
		xmlFreeDoc(obj);
	}
	obj = xmlParseFile([path UTF8String]);
	if (!strcmp((const char*)((xmlDocPtr)obj)->encoding , UTF8Code)) {
		encoding = NSUTF8StringEncoding;
	}else {
		encoding = NSISOLatin1StringEncoding;
	}

	if (!obj) {
		error = [[NSError alloc] initWithDomain:@"file open false." code:200 userInfo:nil];
	}
}

- (void)dealloc
{
	xmlFreeDoc(obj);
	[error	release];
	[super	dealloc];
}

- (MTParseXMLPoint*)getRootPoint
{
	CheckNil;
	return [MTParseXMLPoint objWithPoint:xmlDocGetRootElement(obj)
								   Super:nil 
								Document:self];
}

/*- (MTParseXMLObject*)next
{
	return [MTParseXMLObject objWithPoint:(((xmlDocPtr)self.obj)->next)
									Super:self.superObj 
								 Document:self];
}

- (MTParseXMLObject*)prev
{
	return [MTParseXMLObject objWithPoint:(((xmlDocPtr)self.obj)->prev) 
									Super:self.superObj 
								 Document:self];
}

- (MTParseXMLObject*)child
{
	return [MTParseXMLObject objWithPoint:(((xmlDocPtr)self.obj)->children)
									Super:self.superObj
								 Document:self];
}

- (MTParseXMLObject*)parent
{
	return [MTParseXMLObject objWithPoint:(((xmlDocPtr)self.obj)->parent)
									Super:self.superObj
								 Document:self];
}*/

- (NSString*)name
{
	CheckNil;
	if (!((xmlDocPtr)self.obj)->name) {
		return nil;
	}
	return [NSString stringWithCString:((xmlDocPtr)self.obj)->name encoding:encoding];
}

- (xmlElementType)type
{
	if (!self.obj) {
		return [super type];
	}
	return ((xmlDocPtr)self.obj)->type;
}

@end
